--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
docs/agents/conventions/path-jail.md dev (af76f09d) Text, 2.30 KB
Tc9d1d9# Path jail for local filesystem APIs
Applies when adding or changing HTTP or handler code that lists, reads, writes, uploads, downloads, or deletes files under identity storage or a feature root.
Tc9d1d9## Default threat model
Treat MeshChatX local API access (UI session, shared host, scripted client) as already compromised for the purpose of path checks. The attacker must still fail to:
Tff7b72- Escape the feature root with Ta5d6ff`../`, absolute paths, null bytes, or Windows separators
Tff7b72- Reach sibling identity storage or host paths outside the active identity
Tff7b72- Touch reserved tops (Ta5d6ff`identity`, Ta5d6ff`lxmf`, Ta5d6ff`database.db`, bots, plugins, backups, keys)
Tff7b72- Follow symlinks that point outside the jail
Tff7b72- Exfil via download or content endpoints that skip the same resolve helper
Tff7b72- Upload filenames that smuggle path segments or reserved sidecars
Tc9d1d9## Hard rules
Tff7b721. One dedicated resolve helper per feature root (example: sync-root only for FileSync manager). Do not reuse a looser picker jail for CRUD.
Tff7b722. Normalize then Ta5d6ff`realpath`. Success paths must equal the root or start with Ta5d6ff`root + sep`.
Tff7b723. Fail closed: generic error, HTTP 400 for bad input, never 500 for jail rejects.
Tff7b724. Upload: sanitize to basename only. Join under a resolved parent. Cap size.
Tff7b725. Delete: refuse the root itself. Default to file or empty directory only unless recursive delete is explicit and tested.
Tff7b726. Skip and refuse mutation of dotfiles and protocol sidecars (for FileSync: Ta5d6ff`.rns-filesync*`, Ta5d6ff`.rns-xfer*`).
Tff7b727. Mutating routes stay CSRF-protected HTTP via Ta5d6ff`window.api`. No WS mutators for file CRUD.
Tff7b728. Keep identity-scoped state. Never browse or mutate another identity storage path.
Tc9d1d9## Tests required
Tff7b72- Adversarial traversal and absolute-path cases with bait files that must survive
Tff7b72- Cross-identity bait directory in the same test
Tff7b72- Symlink-out cases (POSIX) for list, read, write, delete
Tff7b72- Oracle or Hypothesis: accept only when resolved path stays under the root
Tff7b72- Frontend mutators go through Ta5d6ff`window.api` (apiFetchGuard stays green)
Full workflow: Ta5d6ff`docs/agents/skills/path-jail-local-fs/SKILL.md`.
Reference implementation: Ta5d6ff`meshchatx/src/backend/rns_filesync_handler.py` (Ta5d6ff`_resolve_manager_path` and manager APIs).
Oracle examples: Ta5d6ff`tests/backend/test_rns_filesync_security.py`, Ta5d6ff`tests/backend/test_path_jail_oracles.py`.
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────